/*
 * @Author: wusd
 * @Date: 2022-06-02 11:23:05
 * @LastEditors: wusd
 * @LastEditTime: 2024-08-23 17:00:07
 * @Description: 公共渲染方法
 *
 */

import { AnyObj, WFormColumn } from 'types/common'
import { searchItem, WSearch } from 'types/table'
import Vue, { CreateElement, VNode } from 'vue'

/**
 * 创建表单元素
 * @param h CreateElement
 * @param params
 * config：每一项的配置
 * model：双向绑定目标对象
 * valueClass：css类名称
 * parentConfig：父级对象配置，例:
 * @returns 虚拟dom
 */

export function renderFormElement(
  h: CreateElement,
  params: {
    config: searchItem | WFormColumn
    model: AnyObj
    valueClass?: string
    parentConfig?: WSearch
    _this?: Vue
  }
) {
  let dom: VNode
  const item = params.config
  const _this = params._this
  const baseConfig = {
    class: params.valueClass,
    ...item?.nodeData,
    props: {
      clearable: true,
      size: item?.size || params?.parentConfig?.size || 'small',
      ...item.nodeData?.props,
      value: params.model[item.prop]
    },
    ref: `ref_${item.type || 'el-input'}_${item.prop}`,
    attrs: {
      ...item.nodeData?.attrs
    },
    on: {
      ...item.nodeData?.on,
      input: (value: any) => {
        /**给渲染项进行v-model赋值 */
        params.model[item.prop] = value
        /**给w-form的v-model进行单独赋值 */
        _this?.$emit('input', {
          ...params.model,
          $fromRender: {
            prop: item.prop,
            value
          }
        })
      }
    }
  }
  if (item.render) {
    dom = item.render(h)
    if (dom?.data) {
      dom.data.class = params.valueClass
    }
    if (dom?.componentOptions) {
      dom.componentOptions.propsData = {
        ...dom?.componentOptions?.propsData,
        value: params.model[item.prop]
      }
      dom.componentOptions.listeners = {
        ...dom.componentOptions.listeners,
        input: (value: any) => {
          params.model[item.prop] = value
          /**
           * 实现w-form的v-model
           * $fromRender告诉w-form组件变更来源
           * */
          _this?.$emit('input', {
            ...params.model,
            $fromRender: {
              prop: item.prop,
              value
            }
          })
        }
      }
    }
  } else if (item.type && ['el-checkbox', 'el-radio'].includes(item.type)) {
    dom = h(item.type, { ...baseConfig, attrs: { ...baseConfig.attrs, label: item.list?.[0].value } }, [
      h('span', item.list?.[0].label + '')
    ])
  } else if (item.type && ['el-checkbox-group', 'el-radio-group'].includes(item.type)) {
    const tag = item.type.split('-')[1]
    dom = h(item.type, baseConfig, [
      item.list?.map(children => {
        return h(
          `el-${tag}${children?.type || ''}`,
          { class: '', attrs: { ...baseConfig.attrs, label: children.value } },
          [h('span', children.label + '')]
        )
      })
    ])
  } else if (item.type === 'el-select') {
    dom = h(item.type, baseConfig, [
      item.list?.map(children => {
        return h(`el-option`, {
          attrs: {
            label: children.label,
            value: children.value
          }
        })
      })
    ])
  } else {
    dom = h(item.type || 'el-input', baseConfig)
  }
  return dom
}

/**
 * 渲染table展示组件，提供v-model功能
 * @param h
 * @param params
 */
export function renderStaticElement(
  h: CreateElement,
  params: {
    componentName: string
    data?: any
    row: AnyObj
    index?: number
    column?: AnyObj
    _this?: Vue
  }
) {
  const baseConfig = {
    ...params.column?.nodeData,
    props: {
      ...params.column?.nodeData?.props,
      value: params.data,
      config_: {
        row: params.row,
        column: params.column,
        index: params.index
      }
    },
    on: {
      ...params.column?.nodeData?.on,
      input: (value: any) => {
        /**给渲染项进行v-model赋值 */
        params.row[params?.column?.prop] = value
        /**给w-form的v-model进行单独赋值 */
        params._this?.$emit('input', value)
      }
    }
  }
  return h(params.componentName, baseConfig)
}
